package testcasetool.transformation.algorithm;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import proyecto.testcasetool.AlternativeFlow;
import proyecto.testcasetool.BasicFlow;
import proyecto.testcasetool.Scenario;
import proyecto.testcasetool.Step;
import proyecto.testcasetool.UseCase;

import testcasetool.transformation.uml.activity.*;

public class Uc2AdTransformation {

	private static ActivityNode generateActivityDiagramImpl(List<Step> flowSteps, Map<String, ActivityNode> nodes, Scenario flow) {
		
		if (flowSteps.isEmpty()) throw new IllegalArgumentException();
		
		Step s = flowSteps.get(0);
		ActivityNode a = nodes.get(s.getId());
		
		
		if (flowSteps.size() == 1) {
			if (flow instanceof BasicFlow) {
				a.connect(new ActivityFinalNode(((UseCase)flow.eContainer()).getPostCondition()));
			} else {
				Step joinStep = ((AlternativeFlow)flow).getJoinStep();
				if (joinStep == null) {
					a.connect(new ActivityFinalNode(((AlternativeFlow)flow).getPostCondition()));
				} else {
					a.connect(nodes.get(joinStep.getId()));
				}
			}
		} else {
			List<Step> tail = flowSteps.subList(1, flowSteps.size());
			ActivityNode nextNode = generateActivityDiagramImpl(tail, nodes, flow);
			if (!s.getAlternativeFlow().isEmpty()) {
				AlternativeFlow alternative = s.getAlternativeFlow().get(0);
				DecisionNode d = new DecisionNode();
				d.connect(nextNode, "Not " + alternative.getCondition());
				d.connect(
						generateActivityDiagramImpl(alternative.getStep(), nodes, alternative), 
						alternative.getCondition());
				a.connect(d);
			} else {
				a.connect(nextNode);
			}
		}
		
		return a;
	}
	

	public static Activity generateActivityDiagram(UseCase uc) {
		Map<String, ActivityNode> nodes = new HashMap<String, ActivityNode>();
		
		Scenario basicFlow = uc.getBasicScenario();
		mapFlowSteps(nodes, basicFlow);
		
		List<AlternativeFlow> alternativeFlows = uc.getAlternativeFlow();
		for (AlternativeFlow altFlow : alternativeFlows) {
			mapFlowSteps(nodes, altFlow);
		}
		Activity ad = new Activity();
		ad.setName(uc.getName());
		ad.setPreCondition(uc.getPreCondition());
		ad.setPostCondition(uc.getPostCondition());
		ad.setUseCase(uc);
		InitialNode start = new InitialNode();
		start.connect(generateActivityDiagramImpl(basicFlow.getStep(), nodes, basicFlow));
		ad.setInitialNode(start);
		
		return ad;
		
	}

	private static void mapFlowSteps(Map<String, ActivityNode> nodes, Scenario flow) {
		for (Step s : flow.getStep()) {
			nodes.put(s.getId(), new Action(s));
		}
	}
	
	
}
